<!DOCTYPE html>
<html lang="en" class="fontColor backGroundColor">
<head>
    <!--适配手机端-->
    <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
    <meta charset="UTF-8">
    <title>首页</title>
    <style>
        *{
            margin: 0;
            padding: 0;

        }
        body,html{
            height: 100%;
            width: 100%;
            background-color: black;
            overflow: hidden;

        }
        .outer{
            display: flex;
            flex-direction: column;
            justify-content: flex-start;
            align-items: center;
            width: 100%;
            height: 100%;

            /*便于实现点击屏幕隐藏底部导航栏*/
            position: relative;
        }

        /*中间书籍文字显示*/
        .book{
            overflow: scroll;
            width: 95%;
            height: 100%;/*注意.fanye使用子绝父相，脱离文档流，不再占位置*/
            color: rgba(255, 255, 255, 0.6);/*书籍字体颜色*/
            font-size: 15px;/*书籍字体大小*/

            /*margin-top: 50px*/

        }
        .book p{
            padding: 3px;
            text-indent: 20px;/*首行缩进*/


        }
        /*底部导航栏*/
        .fanye{
            width: 100%;
            height: 7%;
            display: flex;
            justify-content: space-evenly;
            align-items: center;
            overflow: hidden;

            /*便于实现点击屏幕隐藏底部导航栏*/
            background-color: black;
            position: absolute;
            bottom: 0;
            z-index: 1;

        }
        .fanye .up,.next,.setPageNumber,.setting, .fanye .setting button,input,.fanye,.zhanwei{
            color: rgba(255, 255, 255, 0.6);/*其他乱七八糟的东西的字体颜色*/

        }


        .fanye .pageNumber{
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .fanye .up,.next{
            background-color: rgba(0, 0, 0, 0.84);
           /* color: rgba(255, 255, 255, 0.31);*/
            border: rgba(255, 255, 255, 0.22) 1px solid;

            width: 80px;
            height: 30px;
            border-radius: 2px;
        }
        .fanye .setPageNumber{
            background-color: rgba(0, 0, 0, 0.84);
            /*color: rgba(255, 255, 255, 0.64);*/
            border-radius: 2px;
        }
        .fanye .setting{
            margin-top: 2px;
            height: 100%;
            width: 50%;
            border-right: #1c1a27 1px solid;
            overflow: scroll;
            display: flex;
            flex-direction: column;
          /*  justify-content: space-evenly;*/
            justify-content: space-between;
            align-items: center;

        }
        .fanye .setting button,input{
            margin-top: 2px;
          /*  color: rgba(255, 255, 255, 0.31);*/
            border: rgba(255, 255, 255, 0.22) 1px solid;
            border-radius: 2px;
            background-color: black;
        }

        .fanye .setting .selectColor{
            display: flex;
            margin-top: 3px;
            margin-bottom: 3px;
          border: rgba(197, 146, 255, 0.7) 1px solid;
            border-radius: 2px;
            flex-direction: column;
            align-items: center;
            justify-content: space-evenly;
        }
        .fanye .setting .setFanyeMethod{
            display: flex;
            flex-direction: column;
            margin-top: 3px;
            margin-bottom: 3px;
            border: rgba(197, 146, 255, 0.7) 1px solid;
            border-radius: 2px;
            flex-direction: column;
            align-items: center;
            justify-content: space-evenly;
        }
        .zhanwei{
            display: flex;
            flex-direction: row;
            justify-content: space-evenly;
            align-items: center;
        }
        .zhanwei button{
            background-color: rgba(0, 0, 0, 0.84);
            /* color: rgba(255, 255, 255, 0.31);*/
            border:none;

            width: 80px;
            height: 30px;
            border-radius: 2px;
            color: rgba(255, 255, 255, 0.6);/*其他乱七八糟的东西的字体颜色*/
        }
        .zhanwei select{
            background-color: rgba(0, 0, 0, 0.84);
            /* color: rgba(255, 255, 255, 0.31);*/
            border: none;
            color: rgba(255, 255, 255, 0.6);/*其他乱七八糟的东西的字体颜色*/

        }
        .zhanwei button,select{
            outline:none;/*避免点击之后边框变色*/
        }
    </style>
</head>
<body class="fontColor backGroundColor">
<div class="outer" >
    <!--占位区域高度-->
   <div  oncopy="return false"
         oncut="return false;"
         onselectstart="return false"
         oncontextmenu="return false"
         class="zhanwei" style="width: 95%;height: 8%;">
       <button class="backGroundColor fontColor StopTTS" onclick="stopTTS()" style="display: none">停止</button>
       <button class="backGroundColor fontColor TTSButton" onclick="startTTS()">朗读</button>
       <select class="backGroundColor fontColor speed" >
           <option>1.0</option>
           <option>0.9</option>
           <option>0.8</option>
           <option>0.7</option>
           <option>0.6</option>
           <option>0.5</option>
           <option>1.5</option>
       </select>
       <div style="font-size: 12px;">
            <em  class="currentPageNumber"></em><em >/</em><em class="allPageNumber"></em>
       </div>

    </div>
    <div class="book" onclick="displayOperation()" id="viewerContainer" style=""></div>
    <div class="fanye"  style="display: none" oncopy="return false"
         oncut="return false;"
         onselectstart="return false"
         oncontextmenu="return false" >
        <div class="setting">
            <p class="waring" style="display:none;font-size: 10px;color: red">不要关闭app</p>
            <button class="setPageNumber" onclick="toMainPage()">首页</button>
            <button class="setPageNumber" onclick="setPageNumber()">设置页码</button>
            <!-- <button class="setPageNumber" onclick="setTranslate()">设置翻译源</button>-->
            <button class="setFontSize" onclick="setFontSize()">设置字体大小</button><!--有问题-->
            <div class="selectColor">
                <input  class="colorInput" type="color" placeholder="设置字体颜色" >
                <button  class="setFontColor" onclick="setFontColor()">确认字体颜色</button><!--有问题-->
            </div>

            <div class="selectColor">
                <input  class="colorInput_background" type="color" placeholder="设置背景颜色" >
                <button  class="setBackgroundColor" onclick="setBackgroundColor()">确认背景颜色</button><!--有问题-->
            </div>
            <div class="setFanyeMethod" style="display: none">
                <button onclick="noTransition()">无过渡翻页</button>
                <button onclick="haveTransition()">有过渡翻页</button>
            </div>


        </div>

        <button class="up" onclick="up()" id="up" style="display: none">上一页</button>
        <div class="pageNumber">
            <p class="currentPageNumber"></p>
            <em>/</em>
            <p class="allPageNumber"></p>
        </div>
        <button class="next" onclick="next()" id="next" style="display: none">下一页</button>
    </div>

</div>
</body>
<script src="./static/js/jquery.min.js"></script>
<script src="./static/layer-v3.5.1/layer/layer.js"></script>
<script src="./static/js/md5.min.js"></script>

<!--必要初始化以及翻页按钮、回到主页按钮、设置页面按钮-->
<script>
    let baseUrl="http://"+window.location.host+"/"

    //全局配置,async必须设置为true,不然加载框会一闪而过
    $.ajaxSetup({
        //在请求时显示提示框
        beforeSend: function(jqXHR, settings) {
            layer.load(1, {
                shade: [0.1, '#fff'] //0.1透明度的白色背景
            })
        },
        //请求完毕后（不管成功还是失败），关闭提示框
        complete: function () {
           // layer.closeAll("loading")
        },
        //请求失败时，弹出错误信息
        error: function (jqXHR, status, e) {
            layer.alert('数据请求失败，请后再试!');
        }
    });
    //判断用户是不用应该此时退出
    function canExit () {
        /*
        $.ajax({
            url: baseUrl + "canExit",
            type: 'post',
            async: true,
            beforeSend:function(){
                let waring = document.querySelector(".waring")
                waring.style.display = "block"},
            complete:function(){},
            success: function (data) {
                let waring = document.querySelector(".waring")
                waring.style.display = "none"
            },
            error: function (data) {
                alert("获取书籍列表失败")
            }
        })*/
    }
    //当前页码
    let currentPageNumber=1;
    let allPageNumber=0;

    let convertWhetherOver//setInterval()函数，不断向webview询问speech是否结束

</script>

<!--设置界面字体、背景色等、语言朗读-->
<script>
    function setPageNumber() {
        let input=prompt("请输入页码:")
        if(input == null) {

            return
        }
        let number=parseInt(input)
        if(number<=allPageNumber&&number>=1)
        {
            currentPageNumber=number
            try {
                getPage(currentPageNumber)
            }catch (e) {
                alert(e)
            }

            /*
            currentPageNumber=number;
            $.ajax({
                url:baseUrl+"nextPage",
                type:'post',
                async:true,
                data:{
                    currentPageNumber:currentPageNumber
                },
                success:function (data) {
                    layer.closeAll("loading")
                    let ins=document.querySelector(".book")
                    ins.innerHTML=data;
                    // document.querySelector(".currentPageNumber").innerHTML=currentPageNumber
                    let cpn=document.querySelectorAll(".currentPageNumber")
                    for(let i=0;i<cpn.length;i++)
                    {
                        cpn[i].innerHTML=currentPageNumber
                    }
                    //回到顶部
                    document.querySelector(".book").scrollTop = 0;
                    canExit()
                },
                error:function (data) {
                    alert("获取书籍失败")
                }
            })*/
        }
        else if(number != null)
        {
            alert("页码有误"+number+"\n"+typeof number)
        }

    }
    function toMainPage() {
        window.location.href=baseUrl+'main'
    }
    function setFontSize(f) {
        let book = document.querySelector(".book")
        if(f===undefined||f==null) {
            let font = book.style.fontSize;
            if (font === "")
                font = "15px"
            let input = prompt("请输入字体大小(原:" + font + ")")
            if (input == null && input == undefined)
                return
            try {
                let fontSize = parseInt(input)
                book.style.fontSize = fontSize + "px"
                updateSettings(book.style.backgroundColor,book.style.color,book.style.fontSize)
            } catch (e) {
                alert("字体大小有误")
            }
        }else
        {
            book.style.fontSize=f
        }

    }
    function setFontColor(f) {
        let input=document.querySelector(".colorInput")
        let value
        if(f===undefined||f==null)
        {
            value=input.value
            updateSettings(document.querySelector(".book").style.backgroundColor,value,document.querySelector(".book").style.fontSize)
        }
        else
            value=f
        let book=document.querySelector(".book")
        let fanye=document.querySelectorAll(".fanye .up,.next,.setPageNumber,.setting, .fanye .setting button,input,.fanye,.zhanwei")
        book.style.color=value
        for(let i=0;i<fanye.length;i++)
            fanye[i].style.color=value

        let need=document.querySelectorAll(".fontColor")
        for(let i=0;i<need.length;i++)
            need[i].style.color=value

    }
    function setBackgroundColor(b) {
        let input=document.querySelector(".colorInput_background")
        let value
        if(b===undefined||b==null)
        {
            value=input.value
            updateSettings(value,document.querySelector(".book").style.color,document.querySelector(".book").style.fontSize)
        }
        else
            value=b
        let book=document.querySelector(".book")
        let fanye=document.querySelectorAll(".fanye .up,.next,.setPageNumber,.setting, .fanye .setting button,input,.fanye,.zhanwei")
        book.style.backgroundColor=value
        for(let i=0;i<fanye.length;i++)
            fanye[i].style.backgroundColor=value
        let need=document.querySelectorAll(".backGroundColor")
        for(let i=0;i<need.length;i++)
            need[i].style.backgroundColor=value
    }
    function displayOperation() {
        if(selectedText!=="")//针对选中文字，但是点击空白区域而不选择“取消|复制|翻译”操作的情况
            return
        let fanye=document.querySelector(".fanye")
        let book=document.querySelector(".book")
        if(fanye.style.display==="none")
        {
            // book.style.height="93%"
            fanye.style.display="flex"
            // fanye.style.visibility="visible"
        }
        else
        {
            //   book.style.height="100%"
            fanye.style.display="none"
            //   fanye.style.visibility="hidden"

        }
    }
    function updateSettings(backgroundColor,fontColor,fontSize)
    {
        $.ajax({
            url:baseUrl+"updateSettings",
            type:'post',
            async:false,
            data:{
                backgroundColor: backgroundColor,
                fontColor:fontColor,
                fontSize:fontSize
            },
            beforeSend:function (){},
            success:function (data) {
                layer.closeAll("loading")
            },
            error:function (data) {
                layer.closeAll("loading")
             //   alert("更新设置失败"+(baseUrl+"updateSettings"))
            }
        })

    }
    function startTTS() {
        //获取页面上的文本，此处利用了书籍文字都在.book p标签下这个特性
        let button=document.querySelector(".TTSButton")
        if(button.innerHTML==="朗读") {
            button.innerHTML = "正在加载..."

            //获取当前页文本
            let html=cache[currentPageNumber-1]
            //创建一个元素，便于操作
            let dom=document.createElement("html")
            dom.innerHTML=html
            let passage=dom.querySelectorAll("p")

            let text = ""
            for (let i = 0; i < passage.length; i++) {
                text = text + passage[i].innerHTML
            }
            let rateSelect=document.querySelector(".speed")
            StartMyTTS.callback(text,parseFloat(rateSelect.value))
            // clearInterval(speechWhetherOver)//在webview的回调中
            //由于自带的TTS没有提供朗读结束的回调，只能这样不断询问
           convertWhetherOver=setInterval(function () {
                ConvertWhetherOver.callback()

            },500)
        }
        else if(button.innerHTML==="暂停")
        {
            button.innerHTML="继续"
            PauseMyTTS.callback()
        }
        else if(button.innerHTML==="继续")
        {
            button.innerHTML="暂停"
            let rateSelect=document.querySelector(".speed")
            ContinueMyTTS.callback(parseFloat(rateSelect.value))
        }
    }
    function stopTTS() {
        let button=document.querySelector(".TTSButton")
        button.innerHTML="朗读"
        StopMyTTS.callback()
    }
</script>

<!--左右滑动翻页-->
<!--翻页相关的函数,定义这些函数要在使用这些函数之前-->
<script>
      //无过渡的翻页效果
    function addSlideEventListener(container,upOperate,nextOperate) {
        let startTime = '' // 触摸开始时间
        let startDistanceX = '' // 触摸开始X轴位置
        let startDistanceY = '' // 触摸开始Y轴位置
        let endTime = '' // 触摸结束时间
        let endDistanceX = '' // 触摸结束X轴位置
        let endDistanceY = '' // 触摸结束Y轴位置
        let moveTime = '' // 触摸时间
        let moveDistanceX = '' // 触摸移动X轴距离
        let moveDistanceY = '' // 触摸移动Y轴距离
        container.addEventListener("touchstart", (e) => {
            startTime = new Date().getTime()
            startDistanceX = e.touches[0].screenX
            startDistanceY = e.touches[0].screenY
        })
        container.addEventListener("touchend", (e) => {
            endTime = new Date().getTime()
            endDistanceX = e.changedTouches[0].screenX
            endDistanceY = e.changedTouches[0].screenY
            moveTime = endTime - startTime
            moveDistanceX = startDistanceX - endDistanceX
            moveDistanceY = startDistanceY - endDistanceY
            // console.log(moveDistanceX, moveDistanceY)
            // 判断滑动距离超过40 且 时间小于500毫秒
            if ((Math.abs(moveDistanceX) > 20 || Math.abs(moveDistanceY) > 20) && moveTime < 500) {
                // 判断X轴移动的距离是否大于Y轴移动的距离
                if (Math.abs(moveDistanceX) > Math.abs(moveDistanceY)) {
                    // 左右
                    //console.log(moveDistanceX > 0 ? '左' : '右')
                    if(moveDistanceX>0)
                    {
                        if(nextOperate!=null)
                            nextOperate()
                    }
                    else
                    {
                        if(upOperate!=null)
                            upOperate()
                    }
                } else {
                    // 上下
                    //   console.log(moveDistanceY > 0 ? '上' : '下')
                }
            }
        })

    }
    function removeSlideEventListener(container) {
        let parent=container.parentElement
        let html=parent.innerHTML
        parent.innerHTML=""
        parent.innerHTML=html
    }

</script>
<!--翻页-->
<script>

    function next() {
        if(currentPageNumber<allPageNumber)
        {
            let data=currentPageNumber+1
            $.ajax({
                url:baseUrl+"nextPage",
                type:'post',
                async:true,
                data:{
                    currentPageNumber:data
                },
                success:function (data) {
                    layer.closeAll("loading")
                    let ins=document.querySelector(".book")
                    ins.innerHTML=data;
                    currentPageNumber++
                    // document.querySelector(".currentPageNumber").innerHTML=currentPageNumber
                    let cpn=document.querySelectorAll(".currentPageNumber")
                    for(let i=0;i<cpn.length;i++)
                    {
                        cpn[i].innerHTML=currentPageNumber
                    }

                    //回到顶部
                    document.querySelector(".book").scrollTop = 0;
                    canExit()

                },
                error:function (data) {
                    alert("获取书籍失败")
                }
            })}
        else
            alert("无下一页")
    }
    function up() {
        if(currentPageNumber>1)
        {
            let data=currentPageNumber-1
            $.ajax({
                url:baseUrl+"upPage",
                type:'post',
                async:true,
                data:{
                    currentPageNumber:data
                },
                success:function (data) {
                    layer.closeAll("loading")
                    let ins=document.querySelector(".book")
                    ins.innerHTML=data;
                    //init()
                    currentPageNumber--
                    //document.querySelector(".currentPageNumber").innerHTML=currentPageNumber
                    let cpn=document.querySelectorAll(".currentPageNumber")
                    for(let i=0;i<cpn.length;i++)
                    {
                        cpn[i].innerHTML=currentPageNumber
                    }
                    //回到顶部
                    document.querySelector(".book").scrollTop = 0;
                    canExit()
                },
                error:function (data) {
                    alert("获取书籍失败")
                }
            })}
        else
            alert("无上一页")
    }


</script>
<script>


    function noTransition() {
        let container=document.querySelector(".book")
        container.style.overflow='scroll'
        removeSlideEventListener(document.querySelector(".book"))//先移除，不然会连续翻页两次
        addSlideEventListener( document.querySelector(".book"),function () {
            document.getElementById("up").click()
        },function () {
            document.getElementById("next").click()
        })

    }



</script>
<!--滑动翻页+缓存-->
<script>
    //存储逻辑页面
    let cache=new Array()
    let initCacheHtml=`<div class="fontColor backGroundColor" style=""></div>`//缓冲数组的初始值,在haveTransition函数中初始化
    //有过渡的翻页效果
    function removeSlidePageEventListener(container) {
        let  innerHtml=container.innerHTML
        container.innerHTML=""
        container.innerHTML=innerHtml
    }
    function addSlidePageEventListener(container,wrapper,pages,widthOfPage,heightOfPage,initPageNumber,upOperate,nextOperate) {
        try {
            container.style.width = widthOfPage + "px";
            container.style.height = heightOfPage + "px";
            container.style.overflowX='hidden'
            container.style.overflowY='scroll'
            container.style.position='relative'

            wrapper.style.width = widthOfPage * pages.length + "px";
            wrapper.style.height = heightOfPage + "px";
            wrapper.style.position="absolute"
            wrapper.style.display="flex"
            wrapper.style.border=""//可能会影响宽度，造成难以预料的后果

            for (let i = 0; i < pages.length; i++) {
                pages[i].style.width = widthOfPage + "px";
                pages[i].style.height = heightOfPage + "px";
                pages[i].style.overflowX="hidden"
                pages[i].style.overflowY="scroll"
                pages[i].style.border=""

            }
            // alert(pages.length)
        }catch (e){alert(e)}
        let startDistanceX = '' // 触摸开始X轴位置
        let startDistanceY = '' // 触摸开始Y轴位置
        let endDistanceX = '' // 触摸结束X轴位置
        let endDistanceY = '' // 触摸结束Y轴位置
        let moveDistanceX = '' // 触摸移动X轴距离
        let moveDistanceY = '' // 触摸移动Y轴距离
        if(initPageNumber>=1&&initPageNumber<=pages.length)
        {
            wrapper.style.left=wrapper.offsetLeft-(initPageNumber)*widthOfPage+"px"
        }

        let wrapperAbsolutePosition=wrapper.offsetLeft


        container.addEventListener("touchstart",touchstart)
        //按住ctrl,鼠标点击addEventListener()查看源码，里面的interface GlobalEventHandlersEventMap有包含多少事件
        container.addEventListener("touchmove",touchmove)

        container.addEventListener("touchend",touchend)
        /*定义回调函数*/
        function touchstart(e) {
            startDistanceX = e.touches[0].screenX
            startDistanceY = e.touches[0].screenY
            wrapperAbsolutePosition=wrapper.offsetLeft
            //console.log("最基本位置"+wrapperAbsolutePosition)
        }

        function touchmove(e) {
            let X=e.changedTouches[0].screenX
            let Δx=X-startDistanceX//相对位移
            let Y=e.changedTouches[0].screenY
            let Δy=Y-startDistanceY
            if((Math.abs(Δx)>(Math.abs(Δy))))
                //在存在上/下一页的清空下不断位移不断位移
                if(((Δx>0&&haveUpPage())||(Δx<0&&haveNextPage()))) {
                    wrapper.style.left = wrapperAbsolutePosition + Δx + "px"
                }
        }
        function touchend(e) {
            endDistanceX = e.changedTouches[0].screenX
            endDistanceY = e.changedTouches[0].screenY

            moveDistanceX = startDistanceX - endDistanceX//当大于0时说明是划向下一页
            moveDistanceY = startDistanceY - endDistanceY

            /*一定要在设置style.left时确保前后值>=0.5,不然可能设置了但是没效果*/
            if (((Math.abs(moveDistanceX) > widthOfPage/5))&&(Math.abs(moveDistanceX)>(Math.abs(moveDistanceY)+Math.abs(moveDistanceY)/5))) {//翻页
                if((moveDistanceX>0&&!haveNextPage())||(moveDistanceX<0&&!haveUpPage()))
                    return//处于第一页/最后一页
                /*移除事件监听器，防止在滑动过程中又滑动*/
                container.removeEventListener("touchstart",touchstart,false)
                container.removeEventListener("touchmove",touchmove,false)
                container.removeEventListener("touchend",touchend,false)
                //wrapper最终位置:save
                //翻到上一页时，wrapper当前位置一定小于最终位置
                let save=wrapperAbsolutePosition+widthOfPage//上一页
                if(moveDistanceX>0) //下一页
                    save=wrapperAbsolutePosition-widthOfPage

                //     console.log("初始最终位置："+save)
                let t=setInterval(()=>{ //更新wrapper位置
                    //  alert(moveDistanceX+"\n"+wrapperAbsolutePosition+"\n"+save)
                    if(moveDistanceX>0&&wrapperAbsolutePosition>=save)//下一页
                    {
                        //  alert("s")
                        let offset = -widthOfPage / 40 - 0.1
                        wrapperAbsolutePosition=wrapper.offsetLeft+offset
                        if(wrapperAbsolutePosition>=save)
                            wrapper.style.left=wrapperAbsolutePosition+"px"
                        else
                        {
                            wrapper.style.left=save+"px"
                            //   console.log("结束时最终位置："+save+"位置："+wrapper.style.left)
                            clearInterval(t)
                            nextOperate()
                        }

                    }
                    else if((moveDistanceX<0&&wrapperAbsolutePosition<=save))//上一页
                    {//alert("o")
                        let offset=widthOfPage/40+0.1
                        wrapperAbsolutePosition=wrapper.offsetLeft+offset
                        if(wrapperAbsolutePosition<=save)
                            wrapper.style.left=wrapperAbsolutePosition+"px"
                        else
                        {

                            wrapper.style.left=save+"px"
                            //   console.log("结束时最终位置："+save+"位置："+wrapper.style.left)
                            clearInterval(t)
                            upOperate()
                        }

                    }
                },8)
            }
            else//距离不足，回到原位置
            {
                if (moveDistanceX !== 0&&(wrapper.offsetLeft!==wrapperAbsolutePosition)) {
                    /*移除事件监听器，防止在滑动过程中又滑动*/
                    container.removeEventListener("touchstart", touchstart, false)
                    container.removeEventListener("touchmove", touchmove, false)
                    container.removeEventListener("touchend", touchend, false)
                    let save = wrapperAbsolutePosition//最终位置
                    //开始移动
                    let t = setInterval(() => {
                        //从手指离开位置开始滑动回到原位置
                        // console.log(moveDistanceX+"\n"+wrapperAbsolutePosition+"\n"+save)
                        wrapperAbsolutePosition = wrapper.offsetLeft
                        if ((moveDistanceX>0&&wrapperAbsolutePosition>=save)||(moveDistanceX<0&&wrapperAbsolutePosition<=save))
                        {
                            wrapper.style.left = save + "px"
                            clearInterval(t)
                            container.addEventListener("touchstart", touchstart)
                            //按住ctrl,鼠标点击addEventListener()查看源码，里面的interface GlobalEventHandlersEventMap有包含多少事件
                            container.addEventListener("touchmove", touchmove)
                            container.addEventListener("touchend", touchend)

                        }
                        else {
                            let offset = 0.5
                            if (moveDistanceX < 0)//回退方向
                                offset = -offset
                            wrapperAbsolutePosition = wrapper.offsetLeft + moveDistanceX / 20 + offset
                            wrapper.style.left = wrapperAbsolutePosition + "px"
                        }
                    }, 10)

                }
            }
        }
        //
        function haveNextPage() {
            if(wrapper.offsetLeft>-widthOfPage*(pages.length-1))
                return true;
            return false
        }
        function haveUpPage() {
            if(wrapper.offsetLeft<0)
                return true
            return false
        }

    }
    /*更新滑动容器中的页面*/
    function refreshPageFromWrapper(index) {//index自1开始
        let wrapper=document.querySelector(".wrapper")
        wrapper.style.left=0+"px"
        wrapper.innerHTML=""
        let html=``
        if(index>1)
            html=html+cache[index-2]//前一页
        html=html+cache[index-1]//当前页
        if (index<cache.length)
            html=html+cache[index]//下一页
        wrapper.innerHTML=html
    }
    /*预加载,index自0开始,不要预加载太多会来不及更新页码*/
    function preloading(index,number) {//起始页,预加载几页
        if(number>=0) {
            let end = index + number
            if (end > cache.length)
                end = cache.length

            if (index >= 0) {
                for (let i = index; i < end; i++) {
                    if(cache[i]===initCacheHtml)//不要重复加载,重复加载会丢失更新过的html(更新的scrollTop属性)
                    {
                        $.ajax({
                            url: baseUrl + "getPageNoRefreshPageNumber",
                            type: 'post',
                            async: true,
                            data: {i: (i + 1)},//注意是i+1
                            beforeSend: function (a, b) {
                            },
                            success: function (data) {
                                cache[i] = `<div class="fontColor backGroundColor" style="">` + data + `</div>`
                         //       alert("已加载"+(i+1))
                            },
                            error: function (data) {
                                alert("预加载" + i + "失败")
                            }
                        })
                    }

                }
            }
        }
        else {
            let start = index + number
            if(index>cache.length)
                index=cache.length
            if (start >= 0)
            {
                for (let i = start; i < index; i++) {
                    $.ajax({
                        url: baseUrl + "getPageNoRefreshPageNumber",
                        type: 'post',
                        async: true,
                        data: {i: (i + 1)},//注意是i+1
                        beforeSend: function (a, b) {
                        },
                        success: function (data) {
                            cache[i] = `<div class="fontColor backGroundColor" style="">` + data + `</div>`
                          //  alert((i+1))
                        },
                        error: function (data) {
                            alert("预加载" + (i+1) + "失败")
                        }
                    })
                }
            }
        }
    }
    /*更新后台页码*/
    function refreshPageNumber(pageNumber)
    {
        $.ajax({
            url: baseUrl + "getPage",
            type: 'post',
            async: true,
            data: {
                currentPageNumber: pageNumber
            },
            beforeSend: function (jqXHR, settings) {

            },
            success: function (data) {

            },
            error: function (data) {
                alert("更新页码失败")
            }
        })
    }
    function getPage(pageNumber) {
        try
        {stopTTS()}catch (e) {
            alert(e.toString())
        }
        if(pageNumber<=allPageNumber&&pageNumber>=1) {
            try {
                refreshPageFromWrapper(pageNumber)
            } catch (e) {
                alert(e + "刷新失败")
            }
            removeSlidePageEventListener(document.querySelector(".book"))
            let i = 1
            if (pageNumber === 1)
                i = 0
            let container = document.querySelectorAll(".wrapper div")[i]
            if (container.innerHTML === "")//没有缓存过
            {
                let data = pageNumber
                $.ajax({
                    url: baseUrl + "getPage",
                    type: 'post',
                    async: true,
                    data: {
                        currentPageNumber: data
                    },
                    beforeSend: function (jqXHR, settings) {
                        container.innerHTML = "正在加载..."
                    },
                    success: function (data) {
                        layer.closeAll("loading")
                        container.innerHTML = data;
                        //缓存内容
                        cache[pageNumber - 1] = `<div class="fontColor backGroundColor" style="">` + data + `</div>`
                        try {
                            preloading(pageNumber, 2)
                        }catch (e) {
                            alert("预加载失败")
                        }
                        container.scrollTop = 0
                        let refreshPageInfo = document.querySelectorAll(".currentPageNumber")
                        for (let i = 0; i < refreshPageInfo.length; i++)
                            refreshPageInfo[i].innerHTML = pageNumber

                        let width = document.querySelector('.book').offsetWidth
                        let height = document.querySelector('.book').offsetHeight

                        addSlidePageEventListener(document.querySelector(".book"), document.querySelector(".wrapper"), document.querySelectorAll(".wrapper div"), width, height, i, function () {
                            if (currentPageNumber > 1) {
                                container.setAttribute("scrollTop",container.scrollTop+"")
                                cache[currentPageNumber-1]=container.outerHTML//翻页前更新cache
                                currentPageNumber--
                                getPage(currentPageNumber)

                            }

                        }, function () {
                            if (currentPageNumber < allPageNumber) {
                                container.setAttribute("scrollTop",container.scrollTop+"")
                                cache[currentPageNumber-1]=container.outerHTML//翻页前更新cache
                                currentPageNumber++
                                getPage(currentPageNumber )

                            }

                        })

                        //document.querySelector(".book").scrollTop = 0;
                    },
                    error: function (data) {
                        alert("获取书籍失败")
                    }
                })
            }
            else//已经缓存
            {
              //  alert(container.outerHTML)
                //设置滚动条位置
                container.scrollTop =parseFloat(container.getAttribute("scrollTop"))
                let refreshPageInfo = document.querySelectorAll(".currentPageNumber")
                for (let i = 0; i < refreshPageInfo.length; i++)
                    refreshPageInfo[i].innerHTML = pageNumber

                //
                let width = document.querySelector('.book').offsetWidth
                let height = document.querySelector('.book').offsetHeight
                preloading(pageNumber,2)
                addSlidePageEventListener(document.querySelector(".book"), document.querySelector(".wrapper"), document.querySelectorAll(".wrapper div"), width, height, i, function () {
                    if (currentPageNumber > 1) {
                        //存储滚动条位置
                        container.setAttribute("scrollTop",container.scrollTop+"")
                        cache[currentPageNumber-1]=container.outerHTML//翻页前更新cache

                        currentPageNumber--
                        getPage(currentPageNumber)
                    }

                }, function () {
                    if (currentPageNumber < allPageNumber) {
                        container.setAttribute("scrollTop",container.scrollTop+"")
                        cache[currentPageNumber-1]=container.outerHTML//翻页前更新cache

                        currentPageNumber++
                        getPage(currentPageNumber )
                    }

                })
                refreshPageNumber(pageNumber)
            }
        }
    }
    function haveTransition() {
        let container=document.querySelector(".book")

        removeSlideEventListener(container)
        container=document.querySelector(".book")
        let html=`<div class="wrapper" style=""></div>`
        container.innerHTML=html
        for(let i=0;i<allPageNumber;i++)
        {
            cache[i]=initCacheHtml//初始化缓存
        }
        try {
            preloading(currentPageNumber-1,3)
            getPage(currentPageNumber)
        }catch (e) {
            alert(e+"启动失败")
        }



    }
</script>
<script>
    init().then(result=>{
        try{
            haveTransition()
            //,不在此处加上宽高，可能造成在部分机型上使用设置页码功能跳转页面后，页面高度只有屏幕的一半左右
            let outer=document.querySelector(".outer")
            let html=document.querySelector("html")
            outer.style.width=html.offsetWidth+"px"
            outer.style.height=html.offsetHeight+"px"

        }catch (e) {

            alert(e)
        }
    })
    async function init() {
        //初始化当前页码
        $.ajax({
            url:baseUrl+"getCurrentPageNumber",
            type:'post',
            async:false,
            success:function (data) {
                layer.closeAll("loading")
                currentPageNumber=parseInt(data)
                //   document.querySelector(".currentPageNumber").innerHTML=currentPageNumber
                let cpn=document.querySelectorAll(".currentPageNumber")
                for(let i=0;i<cpn.length;i++)
                {
                    cpn[i].innerHTML=currentPageNumber
                }
            },
            error:function (data) {
                alert("获取当前页码失败")
            }
        })
        //初始化总页码数
        $.ajax({
            url:baseUrl+"getAllPageNumber",
            type:'post',
            async:false,
            success:function (data) {
                layer.closeAll("loading")
                allPageNumber=data
                //    document.querySelector(".allPageNumber").innerHTML=allPageNumber

                let apn=document.querySelectorAll(".allPageNumber")
                for(let i=0;i<apn.length;i++)
                {
                    apn[i].innerHTML=allPageNumber
                }
            },
            error:function (data) {
                alert("获取当前页码失败")
            }
        })
        //初始化页面背景颜色、字体颜色等属性
        $.ajax({
            url:baseUrl+"getSettings",
            type:'post',
            async:false,
            success:function (data) {
                layer.closeAll("loading")
                let settings=data.toString().split("\n")
                setBackgroundColor(settings[0])
                setFontColor(settings[1])
                setFontSize(settings[2])

            },
            error:function (data) {
                alert("获取设置失败")
            }
        })

    }


</script>
<!--获取选中文本并翻译、设置翻译源按钮-->
<script>
    //
    //let translate="baidu"
    function setTranslate() {
        let q=prompt("输入“l”表示使用本地翻译源，输入其他表示百度翻译源")
        if(q!==null)
        {
            if(q==="l")
            {
                translate="l"
            }
            else
                translate="baidu"
        }
    }
    //从百度翻译获取txt的翻译并展示
    //用来给webview拦截到用户选中文本，并点击“翻译”后，使用webview执行的那段js调用的

    let timeoutOfBaiDu=1000*15//初始时设置百度翻译超时时间为15秒，如果有一次查询失败，改成3秒
    function getTranslateFromBaiduAndShowWithPopup(txt) {
        let q=txt.toString().replace(/\n/g,"")//不要用replaceAll();
        //可能会出现奇怪的判读错误
        //if (q!=null && q !=="") {//!!!!!!!!!!!!!!一定不要直接用参数txt，Android端的webview很可能出错
        if(true){
            let title="百度翻译"
            //按理说不可能会传入一个空值，很有可能是那个selectchange函数在用户点击”翻译“的时候还在监听，把selectText变量设置成了""
            //所以每次将selectText设置为空之前都先将其保存在oldText常量中
            if (q==null || q==="")
            {
                title="疑似接收到空值"
                q=oldText.toString().replace(/\n/g,"")//不要用replaceAll();

            }

            let from = "en"
            let to = "zh"
            let salt = 123432//随机码
            //let appid="20230728001761558"
             //let key="14rLgXRjRyw6k5HT0klG"
            /*以下为黄卫民的*/
            let appid = "20221114001452463"
            let key = "7FJNP7Q7el4m5SjGkYoY"

            let ping = appid + q + salt + key
            let sign = md5(ping)
            $.ajax({
                url: "http://api.fanyi.baidu.com/api/trans/vip/translate"+ "?q=" + q.toString() + "&from=en&to=zh&appid="+appid+"&salt=123432&sign=" + sign,
                type: "get",
                dataType: "jsonp",//数据类型为jsonp，不加这个会报，跨域数据请求的错
                // jsonp:"backFunction",//服务端用于接收callBack调用的function名的参数
                async: true,
                timeout:timeoutOfBaiDu,//超时时间为10秒
                data: {},
                success: function (data) {
                    timeoutOfBaiDu=1000*15
                    let result = JSON.stringify(data.trans_result[0].dst)
                    if (q.toString().split(" ").length === 1) {
                        $.ajax({
                            url: baseUrl + "getTranslateFromDic",
                            type: 'post',
                            async: true,
                            timeout:1000*30,
                            data: {text: q.toString()},
                            success: function (data) {
                                try {
                                    layer.closeAll("loading")
                                    result = result + data.toString()
                                    showTranslatePopup(result, title)
                                } catch (e) {
                                    alert(e)
                                }
                            },
                            error: function (data) {
                                alert("本地词典查词失败")
                            }
                        })
                    } else {
                        // document.querySelector(".middle img").src="/static/images/result.png"
                        // alert("获取的翻译数据：" + data.trans_result[0].dst)
                        layer.closeAll("loading")

                        showTranslatePopup(JSON.stringify(data.trans_result[0].dst), title)
                    }
                    //alert(JSON.stringify(data.trans_result[0].dst))
                },
                error: function (data) {
                    console.log(data)
                    layer.closeAll("loading")
                    timeoutOfBaiDu=1000*3
                    if (q.toString().split(" ").length === 1) {
                        $.ajax({
                            url: baseUrl + "getTranslateFromDic",
                            type: 'post',
                            async: true,
                            timeout:1000*30,
                            data: {text: q.toString()},
                            success: function (data) {
                                try {
                                    layer.closeAll("loading")
                                    showTranslatePopup(`<p>调用百度翻译失败</p>`+data.toString(), title)
                                } catch (e) {
                                    alert(e)
                                }
                            },
                            error: function (data) {
                                alert("本地词典查词失败")
                            }
                        })
                    } else {
                        // document.querySelector(".middle img").src="/static/images/result.png"
                        // alert("获取的翻译数据：" + data.trans_result[0].dst)
                        layer.closeAll("loading")
                        showTranslatePopup(JSON.stringify(data.trans_result[0].dst), title)
                    }
                    //alert(JSON.stringify(data.trans_result[0].dst))
                    //  alert("调用百度翻译失败")
                }
            })
        }
        else {
            //   let text=document.querySelector(".zhanwei .selectedTextContent").innerHTML
            // showTranslatePopup("<p>selectedText:@" + selectedText + "@<p>Text:@"+"<p>"+text+"@</p>"+"@<p>oldText:@"+"<p>"+oldText+"@</p>", "系统疑似接收到空值")


        }

    }

    //从本地机器翻译获取txt的翻译并展示
    function getTranslateFromLocalAndShowWithPopup(txt) {
        let toString = txt.toString().replace(/\n/g,"")//.replaceAll("\n","")//webview上使用这个函数会出错
        //alert(txt+"\n"+typeof txt+"\n"+(txt!=null)+"\n"+(txt!==""))
        if (toString != null && toString !== "") {//!!!!!!!!!!!!!!一定不要直接用参数txt，Android端的webview很可能出错
            //  alert(toString+"sax\n")
            //   let q = txt.replaceAll("\n", "")
            $.ajax({
                url: baseUrl +"getLocalTranslate",
                async: true,
                data: {//!!!!!!!!!!!!!!一定不要直接用参数txt
                    text:toString// q.toString()
                },
                success: function (data) {
                    layer.closeAll("loading")
                    showTranslatePopup(data,"本地翻译")
                },
                error: function (data) {
                    alert("翻译失败")
                }

            })
        }

    }

    //将传入的文本o以弹窗的形式展示出来
    function showTranslatePopup(o,title) {
        layer.open({
            type: 1,
            skin: 'layui-layer-demo', //样式类名
            closeBtn: 0, //显示关闭按钮(0不显示)
            anim: 2,
            shadeClose: true, //开启遮罩关闭(就是点击空白部分自动关闭)
            //后台返回的是HTML
            content: '<div style="font-size: 17px;text-indent: 20px;color: red;word-wrap: break-word;overflow-y: auto;">' + o + '</div>',//可以是html
            title:`<p oncopy="return false"
         oncut="return false;"
         onselectstart="return false"
         oncontextmenu="return false" style="padding:0;color: red ;">${title}</p>`,//没有title
            resize: false,//不允许拉伸
            move: ".layui-layer-title"//触发拖动元素，默认时title，改成content,手机端浏览器无法拖动
            ,offset:['200px','30px']//弹出框在屏幕的位置,你可以offset: '100px'。当您top、left都要定义时，你可以offset: ['100px', '200px']。除此之外，你还可以定义offset: 'rb'，表示右下角。
        });

        /*设置弹出框内容的背景色*/
        document.querySelector(".layui-layer-demo").style.backgroundColor = "rgba(1,1,1,0.5)"
        document.querySelector(".layui-layer-demo").style.width = "300px"
        document.querySelector(".layui-layer-demo").style.height = "350px"
        document.querySelector(".layui-layer-demo").style.display= "flex"
        document.querySelector(".layui-layer-demo").style.flexDirection='column'
        /*设置标题的颜色和样式*/
        document.querySelector(".layui-layer-title").style.backgroundColor = "rgba(130,17,31,0.4)"
        document.querySelector(".layui-layer-title").style.height='50px'
        document.querySelector(".layui-layer-title").style.height='50px'
        document.querySelector(".layui-layer-title").style.padding='0'//清除自带的padding
        document.querySelector(".layui-layer-title").style.display= "flex"
        document.querySelector(".layui-layer-title").style.justifyContent= "center"
        document.querySelector(".layui-layer-title").style.alignItems= "center"

        /*layui在手机端无法拖拽*/
        if(navigator.userAgent.match("Android")||navigator.userAgent.match("IOS"))
        {
            dragAndDropForPhone(document.querySelector(".layui-layer-title"),document.querySelector(".layui-layer-demo"))
        }
    }
    /*监听选中文字*/
    let selectedText=""
    let oldText="";
    if(navigator.userAgent.match("Android")||navigator.userAgent.match("IOS"))//Iphone不知道管用不
    {
        document.addEventListener('selectionchange', MyFunction);
        function MyFunction() {
            oldText=document.getSelection().toString()
            if(oldText==null||oldText==="")
            {
                oldText=selectedText
            }
            selectedText=document.getSelection().toString()


            //let selectedTextContent=document.querySelector(".zhanwei .selectedTextContent")
            //selectedTextContent.innerHTML=selectedText
        }
    }
    /*专门给手机端写的函数，实现翻译框的拖动，传入想拖动的WebElement和他的父盒子*/
    /*
    * <div class="parent"><div class="son"></div></div>
    * parent=document.querySelector(".parent")
    * e=document.querySelector(".son")
    * */
    function dragAndDropForPhone(e,parent) {
        var startX = 0; // 获取手指初始坐标
        var startY = 0;
        var x = 0; // 获得盒子原来的位置
        var y = 0;
        // 手指触摸
        e.addEventListener('touchstart', function(e) {
            //  获取手指初始坐标
            startX = e.targetTouches[0].pageX;
            startY = e.targetTouches[0].pageY;
            //x = this.offsetLeft;
            //y = this.offsetTop;
            x=parent.offsetLeft
            y=parent.offsetTop;
            //this.style.boxShadow = '0 0 15px rgba(0, 0, 0, .6)';
            parent.style.boxShadow = '0 0 15px rgba(0, 0, 0, .6)';
        });
        // 手指离开
        e.addEventListener('touchend', function(e) {
            //this.style.boxShadow = '';
            parent.style.boxShadow = '';
        });

        // 手指按住移动
        e.addEventListener('touchmove', function(e) {
            //  计算手指的移动距离：手指移动之后的坐标减去手指初始的坐标
            var moveX = e.targetTouches[0].pageX - startX;
            var moveY = e.targetTouches[0].pageY - startY;
            // 移动盒子 盒子原来的位置 + 手指移动的距离

            //this.style.left = x + moveX + 'px';
            //this.style.top = y + moveY + 'px';
            parent.style.left = x + moveX + 'px';
            parent.style.top = y + moveY + 'px';
            e.preventDefault(); // 阻止屏幕滚动的默认行为
        });

    }
</script>
</html>